home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / nt / source.exe / POSIX / MAKE / BUF.C < prev    next >
C/C++ Source or Header  |  1992-06-29  |  11KB  |  437 lines

  1. /*
  2.  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
  3.  * Copyright (c) 1988, 1989 by Adam de Boor
  4.  * Copyright (c) 1989 by Berkeley Softworks
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Adam de Boor.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  * 3. All advertising materials mentioning features or use of this software
  19.  *    must display the following acknowledgement:
  20.  *    This product includes software developed by the University of
  21.  *    California, Berkeley and its contributors.
  22.  * 4. Neither the name of the University nor the names of its contributors
  23.  *    may be used to endorse or promote products derived from this software
  24.  *    without specific prior written permission.
  25.  *
  26.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  27.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36.  * SUCH DAMAGE.
  37.  */
  38.  
  39. #ifndef lint
  40. static char sccsid[] = "@(#)buf.c    5.5 (Berkeley) 12/28/90";
  41. #endif /* not lint */
  42.  
  43. /*-
  44.  * buf.c --
  45.  *    Functions for automatically-expanded buffers.
  46.  */
  47.  
  48. #include    "sprite.h"
  49. #include    "buf.h"
  50.  
  51. #ifndef max
  52. #define max(a,b)  ((a) > (b) ? (a) : (b))
  53. #endif
  54.  
  55. /*
  56.  * BufExpand --
  57.  *     Expand the given buffer to hold the given number of additional
  58.  *    bytes.
  59.  *    Makes sure there's room for an extra NULL byte at the end of the
  60.  *    buffer in case it holds a string.
  61.  */
  62. #define BufExpand(bp,nb) \
  63.      if (bp->left < (nb)+1) {\
  64.         int newSize = (bp)->size + max((nb)+1,BUF_ADD_INC); \
  65.         Byte  *newBuf = (Byte *) realloc((bp)->buffer, newSize); \
  66.         \
  67.         (bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \
  68.         (bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer);\
  69.         (bp)->buffer = newBuf;\
  70.         (bp)->size = newSize;\
  71.         (bp)->left = newSize - ((bp)->inPtr - (bp)->buffer);\
  72.     }
  73.  
  74. #define BUF_DEF_SIZE    256     /* Default buffer size */
  75. #define BUF_ADD_INC    256     /* Expansion increment when Adding */
  76. #define BUF_UNGET_INC    16      /* Expansion increment when Ungetting */
  77.  
  78. /*-
  79.  *-----------------------------------------------------------------------
  80.  * Buf_OvAddByte --
  81.  *    Add a single byte to the buffer.  left is zero or negative.
  82.  *
  83.  * Results:
  84.  *    None.
  85.  *
  86.  * Side Effects:
  87.  *    The buffer may be expanded.
  88.  *
  89.  *-----------------------------------------------------------------------
  90.  */
  91. void
  92. Buf_OvAddByte (bp, byte)
  93.     register Buffer bp;
  94.     Byte    byte;
  95. {
  96.  
  97.     bp->left = 0;
  98.     BufExpand (bp, 1);
  99.  
  100.     *bp->inPtr++ = byte;
  101.     bp->left--;
  102.  
  103.     /*
  104.      * Null-terminate
  105.      */
  106.     *bp->inPtr = 0;
  107. }
  108.  
  109. /*-
  110.  *-----------------------------------------------------------------------
  111.  * Buf_AddBytes --
  112.  *    Add a number of bytes to the buffer.
  113.  *
  114.  * Results:
  115.  *    None.
  116.  *
  117.  * Side Effects:
  118.  *    Guess what?
  119.  *
  120.  *-----------------------------------------------------------------------
  121.  */
  122. void
  123. Buf_AddBytes (bp, numBytes, bytesPtr)
  124.     register Buffer bp;
  125.     int        numBytes;
  126.     Byte    *bytesPtr;
  127. {
  128.  
  129.     BufExpand (bp, numBytes);
  130.  
  131.     bcopy (bytesPtr, bp->inPtr, numBytes);
  132.     bp->inPtr += numBytes;
  133.     bp->left -= numBytes;
  134.  
  135.     /*
  136.      * Null-terminate
  137.      */
  138.     *bp->inPtr = 0;
  139. }
  140.  
  141. /*-
  142.  *-----------------------------------------------------------------------
  143.  * Buf_UngetByte --
  144.  *    Place the byte back at the beginning of the buffer.
  145.  *
  146.  * Results:
  147.  *    SUCCESS if the byte was added ok. FAILURE if not.
  148.  *
  149.  * Side Effects:
  150.  *    The byte is stuffed in the buffer and outPtr is decremented.
  151.  *
  152.  *-----------------------------------------------------------------------
  153.  */
  154. void
  155. Buf_UngetByte (bp, byte)
  156.     register Buffer bp;
  157.     Byte    byte;
  158. {
  159.  
  160.     if (bp->outPtr != bp->buffer) {
  161.     bp->outPtr--;
  162.     *bp->outPtr = byte;
  163.     } else if (bp->outPtr == bp->inPtr) {
  164.     *bp->inPtr = byte;
  165.     bp->inPtr++;
  166.     bp->left--;
  167.     *bp->inPtr = 0;
  168.     } else {
  169.     /*
  170.      * Yech. have to expand the buffer to stuff this thing in.
  171.      * We use a different expansion constant because people don't
  172.      * usually push back many bytes when they're doing it a byte at
  173.      * a time...
  174.      */
  175.     int       numBytes = bp->inPtr - bp->outPtr;
  176.     Byte      *newBuf;
  177.  
  178.     newBuf = (Byte *)emalloc(bp->size + BUF_UNGET_INC);
  179.     bcopy ((char *)bp->outPtr,
  180.             (char *)(newBuf+BUF_UNGET_INC), numBytes+1);
  181.     bp->outPtr = newBuf + BUF_UNGET_INC;
  182.     bp->inPtr = bp->outPtr + numBytes;
  183.     free ((char *)bp->buffer);
  184.     bp->buffer = newBuf;
  185.     bp->size += BUF_UNGET_INC;
  186.     bp->left = bp->size - (bp->inPtr - bp->buffer);
  187.     bp->outPtr -= 1;
  188.     *bp->outPtr = byte;
  189.     }
  190. }
  191.  
  192. /*-
  193.  *-----------------------------------------------------------------------
  194.  * Buf_UngetBytes --
  195.  *    Push back a series of bytes at the beginning of the buffer.
  196.  *
  197.  * Results:
  198.  *    None.
  199.  *
  200.  * Side Effects:
  201.  *    outPtr is decremented and the bytes copied into the buffer.
  202.  *
  203.  *-----------------------------------------------------------------------
  204.  */
  205. void
  206. Buf_UngetBytes (bp, numBytes, bytesPtr)
  207.     register Buffer bp;
  208.     int        numBytes;
  209.     Byte    *bytesPtr;
  210. {
  211.  
  212.     if (bp->outPtr - bp->buffer >= numBytes) {
  213.     bp->outPtr -= numBytes;
  214.     bcopy (bytesPtr, bp->outPtr, numBytes);
  215.     } else if (bp->outPtr == bp->inPtr) {
  216.     Buf_AddBytes (bp, numBytes, bytesPtr);
  217.     } else {
  218.     int       curNumBytes = bp->inPtr - bp->outPtr;
  219.     Byte      *newBuf;
  220.     int       newBytes = max(numBytes,BUF_UNGET_INC);
  221.  
  222.     newBuf = (Byte *)emalloc (bp->size + newBytes);
  223.     bcopy((char *)bp->outPtr, (char *)(newBuf+newBytes), curNumBytes+1);
  224.     bp->outPtr = newBuf + newBytes;
  225.     bp->inPtr = bp->outPtr + curNumBytes;
  226.     free ((char *)bp->buffer);
  227.     bp->buffer = newBuf;
  228.     bp->size += newBytes;
  229.     bp->left = bp->size - (bp->inPtr - bp->buffer);
  230.     bp->outPtr -= numBytes;
  231.     bcopy ((char *)bytesPtr, (char *)bp->outPtr, numBytes);
  232.     }
  233. }
  234.  
  235. /*-
  236.  *-----------------------------------------------------------------------
  237.  * Buf_GetByte --
  238.  *    Return the next byte from the buffer. Actually returns an integer.
  239.  *
  240.  * Results:
  241.  *    Returns BUF_ERROR if there's no byte in the buffer, or the byte
  242.  *    itself if there is one.
  243.  *
  244.  * Side Effects:
  245.  *    outPtr is incremented and both outPtr and inPtr will be reset if
  246.  *    the buffer is emptied.
  247.  *
  248.  *-----------------------------------------------------------------------
  249.  */
  250. int
  251. Buf_GetByte (bp)
  252.     register Buffer bp;
  253. {
  254.     int        res;
  255.  
  256.     if (bp->inPtr == bp->outPtr) {
  257.     return (BUF_ERROR);
  258.     } else {
  259.     res = (int) *bp->outPtr;
  260.     bp->outPtr += 1;
  261.     if (bp->outPtr == bp->inPtr) {
  262.         bp->outPtr = bp->inPtr = bp->buffer;
  263.         bp->left = bp->size;
  264.         *bp->inPtr = 0;
  265.     }
  266.     return (res);
  267.     }
  268. }
  269.  
  270. /*-
  271.  *-----------------------------------------------------------------------
  272.  * Buf_GetBytes --
  273.  *    Extract a number of bytes from the buffer.
  274.  *
  275.  * Results:
  276.  *    The number of bytes gotten.
  277.  *
  278.  * Side Effects:
  279.  *    The passed array is overwritten.
  280.  *
  281.  *-----------------------------------------------------------------------
  282.  */
  283. int
  284. Buf_GetBytes (bp, numBytes, bytesPtr)
  285.     register Buffer bp;
  286.     int        numBytes;
  287.     Byte    *bytesPtr;
  288. {
  289.     
  290.     if (bp->inPtr - bp->outPtr < numBytes) {
  291.     numBytes = bp->inPtr - bp->outPtr;
  292.     }
  293.     bcopy (bp->outPtr, bytesPtr, numBytes);
  294.     bp->outPtr += numBytes;
  295.  
  296.     if (bp->outPtr == bp->inPtr) {
  297.     bp->outPtr = bp->inPtr = bp->buffer;
  298.     bp->left = bp->size;
  299.     *bp->inPtr = 0;
  300.     }
  301.     return (numBytes);
  302. }
  303.  
  304. /*-
  305.  *-----------------------------------------------------------------------
  306.  * Buf_GetAll --
  307.  *    Get all the available data at once.
  308.  *
  309.  * Results:
  310.  *    A pointer to the data and the number of bytes available.
  311.  *
  312.  * Side Effects:
  313.  *    None.
  314.  *
  315.  *-----------------------------------------------------------------------
  316.  */
  317. Byte *
  318. Buf_GetAll (bp, numBytesPtr)
  319.     register Buffer bp;
  320.     int        *numBytesPtr;
  321. {
  322.  
  323.     if (numBytesPtr != (int *)NULL) {
  324.     *numBytesPtr = bp->inPtr - bp->outPtr;
  325.     }
  326.     
  327.     return (bp->outPtr);
  328. }
  329.  
  330. /*-
  331.  *-----------------------------------------------------------------------
  332.  * Buf_Discard --
  333.  *    Throw away bytes in a buffer.
  334.  *
  335.  * Results:
  336.  *    None.
  337.  *
  338.  * Side Effects:
  339.  *    The bytes are discarded. 
  340.  *
  341.  *-----------------------------------------------------------------------
  342.  */
  343. void
  344. Buf_Discard (bp, numBytes)
  345.     register Buffer bp;
  346.     int        numBytes;
  347. {
  348.  
  349.     if (bp->inPtr - bp->outPtr <= numBytes) {
  350.     bp->inPtr = bp->outPtr = bp->buffer;
  351.     bp->left = bp->size;
  352.     *bp->inPtr = 0;
  353.     } else {
  354.     bp->outPtr += numBytes;
  355.     }
  356. }
  357.  
  358. /*-
  359.  *-----------------------------------------------------------------------
  360.  * Buf_Size --
  361.  *    Returns the number of bytes in the given buffer. Doesn't include
  362.  *    the null-terminating byte.
  363.  *
  364.  * Results:
  365.  *    The number of bytes.
  366.  *
  367.  * Side Effects:
  368.  *    None.
  369.  *
  370.  *-----------------------------------------------------------------------
  371.  */
  372. int
  373. Buf_Size (buf)
  374.     Buffer  buf;
  375. {
  376.     return (buf->inPtr - buf->outPtr);
  377. }
  378.  
  379. /*-
  380.  *-----------------------------------------------------------------------
  381.  * Buf_Init --
  382.  *    Initialize a buffer. If no initial size is given, a reasonable
  383.  *    default is used.
  384.  *
  385.  * Results:
  386.  *    A buffer to be given to other functions in this library.
  387.  *
  388.  * Side Effects:
  389.  *    The buffer is created, the space allocated and pointers
  390.  *    initialized.
  391.  *
  392.  *-----------------------------------------------------------------------
  393.  */
  394. Buffer
  395. Buf_Init (size)
  396.     int        size;     /* Initial size for the buffer */
  397. {
  398.     Buffer bp;          /* New Buffer */
  399.  
  400.     bp = (Buffer)emalloc(sizeof(*bp));
  401.  
  402.     if (size <= 0) {
  403.     size = BUF_DEF_SIZE;
  404.     }
  405.     bp->left = bp->size = size;
  406.     bp->buffer = (Byte *)emalloc(size);
  407.     bp->inPtr = bp->outPtr = bp->buffer;
  408.     *bp->inPtr = 0;
  409.  
  410.     return (bp);
  411. }
  412.  
  413. /*-
  414.  *-----------------------------------------------------------------------
  415.  * Buf_Destroy --
  416.  *    Nuke a buffer and all its resources.
  417.  *
  418.  * Results:
  419.  *    None.
  420.  *
  421.  * Side Effects:
  422.  *    The buffer is freed.
  423.  *
  424.  *-----------------------------------------------------------------------
  425.  */
  426. void
  427. Buf_Destroy (buf, freeData)
  428.     Buffer  buf;      /* Buffer to destroy */
  429.     Boolean freeData;    /* TRUE if the data should be destroyed as well */
  430. {
  431.     
  432.     if (freeData) {
  433.     free ((char *)buf->buffer);
  434.     }
  435.     free ((char *)buf);
  436. }
  437.